package com.hnust.controller.paper.paperManagement;

import com.hnust.controller.MainController;
import com.hnust.controller.paper.component.PreviewPaperController;
import com.hnust.domain.*;
import com.hnust.fx.FXMLController;
import com.hnust.service.TestPaperService;
import com.hnust.store.DataStore;
import com.hnust.store.PaperListDataStore;
import com.hnust.view.paper.component.PreviewPaperView;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.geometry.Pos;
import javafx.scene.control.*;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.HBox;

import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.stage.StageStyle;
import javafx.util.Callback;
import org.springframework.beans.factory.annotation.Autowired;
import retrofit2.Call;
import retrofit2.Response;

import java.io.IOException;
import java.net.URL;
import java.util.*;
import java.util.stream.Collectors;

@FXMLController
public class PaperListController implements Initializable {
    @Autowired
    private PreviewPaperView previewPaperView;
    @Autowired
    private TestPaperService testPaperService;
    @Autowired
    private PreviewPaperController PreviewPaperContoller;
    @Autowired
    private MainController mainController;
    @Autowired
    private DataStore dataStore;
    @Autowired
    private PaperListDataStore paperListDataStore;
    @FXML
    TableView<PaperData> tableView;
    @FXML
    public ComboBox<String> courseNameCombox;
    @FXML
    public TableColumn<PaperData,Boolean> columnChoice;
    @FXML
    public TableColumn<PaperData,String> columnSubject;
    @FXML
    public TableColumn<PaperData,String> columnPerson;
    @FXML
    public TableColumn<PaperData,String> columnTime;
    @FXML
    public TableColumn<PaperData,Integer> columnAB;
    @FXML
    public TableColumn<PaperData,Integer> columnSample;
    @FXML
    public TableColumn<PaperData,String> columnOperate;
    @FXML
    public Pagination page;
    @FXML
    public TextField toPage;
    @FXML
    public Button autoPaper;
    @FXML
    public ScrollPane container;
    @FXML
    public AnchorPane contain;
    @FXML
    public Button generatePaper;

    private ObservableList<PaperData> paperDatalist=FXCollections.observableArrayList();
    private List<CourseData> courseDataList=new ArrayList<>();
    private ObservableList<String> courseList= FXCollections.observableArrayList();
    private String defaultValue="暂未加入课程组";
    private String allValue="全部";
    private int pageNumber=1;
    private int bFlag=0;
    private CheckBox cb;
    @Override
    public void initialize(URL location, ResourceBundle resources) {
        container.parentProperty().addListener((observable, oldValue, newValue) -> {
            if(newValue!=null){
                getCombData();
                getTableViewData(null);
            }else{
                clear();
            }
        });
        listenChange();
        setListener();
        initTableView();
    }

    //边框大小监听
    public void listenChange() {
        //通过监听最外层容器的宽度，来改变内层Anchor的宽度
        container.widthProperty().addListener(new ChangeListener<Number>() {
            @Override
            public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
                contain.setPrefWidth((double) newValue - 2);
            }
        });
        //通过监听最外层容器的高度，来改变内层Anchor的高度
        container.heightProperty().addListener(new ChangeListener<Number>() {
            @Override
            public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
                contain.setPrefHeight((double) newValue - 2);
            }
        });
    }

    //初始化TableView
    public void initTableView(){
        //设置第一列（全选）
        cb=new CheckBox();
        cb.setSelected(false);
        //全选/取消全选
        cb.selectedProperty().addListener(new ChangeListener<Boolean>() {
            @Override
            public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
                if (newValue==true) {
                    tableView.getItems().stream().forEach(paperData -> paperData.setChecked(true));
                } else {
                    if(tableView.getItems().stream().anyMatch(paperData -> paperData.getChecked()==false)){

                    }else{
                        tableView.getItems().stream().forEach(paperData -> paperData.setChecked(false));
                    }
                }
                tableView.refresh();
            }
        });
        columnChoice.setGraphic(cb);//表头全选框
        columnChoice.setSortable(false);
        columnChoice.setCellValueFactory(new PropertyValueFactory<PaperData,Boolean>("checked"));
        columnChoice.setCellFactory(new Callback<TableColumn<PaperData, Boolean>, TableCell<PaperData, Boolean>>() {
            @Override
            public TableCell<PaperData, Boolean> call(TableColumn<PaperData, Boolean> param) {
                TableCell<PaperData,Boolean> cell=new TableCell<PaperData,Boolean>(){
                    @Override
                    protected void updateItem(Boolean item, boolean empty) {
                        final TableCell cell=this;
                        super.updateItem(item, empty);
                        if(empty==false){
                            HBox hBox=new HBox();
                            hBox.setAlignment(Pos.CENTER);
                            CheckBox checkBox=new CheckBox();
                            checkBox.setSelected(item);
                            //给CheckBox添加变化事件
                            checkBox.selectedProperty().addListener(new ChangeListener<Boolean>() {
                                @Override
                                public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
                                    PaperData data= (PaperData) cell.getTableRow().getItem();
                                    if(newValue==true){
                                        data.setChecked(newValue);
                                        Boolean bl=tableView.getItems().stream().anyMatch(paperData -> paperData.getChecked()==false);
                                        if(bl==false){
                                            cb.setSelected(true);
                                        }
                                    }else {
                                        data.setChecked(false);
                                        cb.setSelected(false);
                                    }
                                    tableView.refresh();
                                }
                            });
                            hBox.getChildren().add(checkBox);
                            this.setGraphic(hBox);
                        }
                    }
                };
                return cell;
            }
        });
        columnChoice.setPrefWidth(20);
        //设置第列二（科目）
        columnSubject.setCellValueFactory(new PropertyValueFactory<PaperData,String>("courseName"));
        //设置第三列（创建人）
        columnPerson.setCellValueFactory(new PropertyValueFactory<PaperData,String>("teaName"));
        //设置第四列（创建时间）
        columnTime.setCellValueFactory(new PropertyValueFactory<PaperData,String>("createTime"));
        //设置第五列（试卷类型）
        columnAB.setCellValueFactory(new PropertyValueFactory<PaperData,Integer>("isAB"));
        columnAB.setCellFactory(new Callback<TableColumn<PaperData, Integer>, TableCell<PaperData, Integer>>() {
            @Override
            public TableCell<PaperData, Integer> call(TableColumn<PaperData, Integer> param) {
                TableCell<PaperData, Integer> cell=new TableCell<PaperData,Integer>(){
                    @Override
                    protected void updateItem(Integer item, boolean empty) {
                        super.updateItem(item, empty);
                        if(empty==false){
                            Label label=new Label();
                            if(item==1){
                                label.setText("A卷");
                            }else{
                                label.setText("B卷");
                            }
                            label.setStyle("-fx-font-weight: bold;-fx-text-fill: #000");
                            this.setGraphic(label);
                        }else{
                            this.setGraphic(null);
                        }
                    }
                };
                return cell;
            }
        });
        //设置第六列（试卷类型）
        columnSample.setCellValueFactory(new PropertyValueFactory<PaperData,Integer>("isSample"));
        columnSample.setCellFactory(new Callback<TableColumn<PaperData, Integer>, TableCell<PaperData, Integer>>() {
            @Override
            public TableCell<PaperData, Integer> call(TableColumn<PaperData, Integer> param) {
                TableCell<PaperData, Integer> cell=new TableCell<PaperData,Integer>(){
                    @Override
                    protected void updateItem(Integer item, boolean empty) {
                        super.updateItem(item, empty);
                        if(empty==false){
                            Label label=new Label();
                            if(item==1){
                                label.setText("是");
                            }else{
                                label.setText("否");
                            }
                            label.setStyle("-fx-font-weight: bold;-fx-text-fill: #000");
                            this.setGraphic(label);
                        }else{
                            this.setGraphic(null);
                        }
                    }
                };
                return cell;
            }
        });
        //设置第七列（操作）
        columnOperate.setCellValueFactory(new PropertyValueFactory<PaperData,String>("papId"));
        columnOperate.setCellFactory(new Callback<TableColumn<PaperData, String>, TableCell<PaperData, String>>() {
            @Override
            public TableCell<PaperData, String> call(TableColumn<PaperData, String> param) {
                TableCell<PaperData, String> cell=new TableCell<PaperData, String>(){
                    @Override
                    protected void updateItem(String item, boolean empty) {
                        super.updateItem(item, empty);
                        if(empty==false){
                            List<String> list=new ArrayList<>();
                            list.add(item);
                            HBox hBox=new HBox();
                            hBox.setAlignment(Pos.CENTER);
                            hBox.setSpacing(10);
                            Hyperlink h1=new Hyperlink("预览");
                            //TODO 增加详情弹窗
                            h1.setOnAction(new EventHandler<ActionEvent>(){
                                @Override
                                public void handle(ActionEvent event) {
                                    paperListDataStore.setPaper_id(item);
                                    Dialog dialog=new Dialog();
                                    DialogPane dialogPane=new DialogPane();
                                    dialogPane.setStyle("-fx-background-color: #FFF;-fx-border-width: 2;-fx-border-color: #ADADAD");
                                    dialogPane.setContent(previewPaperView.getView());
                                    dialog.setDialogPane(dialogPane);
                                    dialog.setTitle("试卷预览");
                                    dialog.initStyle(StageStyle.UNDECORATED);
                                    dialog.setGraphic(null);
                                    ButtonType ok=new ButtonType("确定", ButtonBar.ButtonData.OK_DONE);
                                    ButtonType cancel=new ButtonType("取消", ButtonBar.ButtonData.CANCEL_CLOSE);
                                    dialog.getDialogPane().getButtonTypes().addAll(ok,cancel);
                                    Optional<ButtonType> result=dialog.showAndWait();
                                    if(result.get()==ok){

                                    }
                                }
                            });
                            Hyperlink h2=new Hyperlink("设为样卷");
                            h2.setOnAction(new EventHandler<ActionEvent>(){
                                @Override
                                public void handle(ActionEvent event) {
                                    testPaperService.changePaperType(new retrofit2.Callback<Result<Integer>>() {
                                        @Override
                                        public void onResponse(Call<Result<Integer>> call, Response<Result<Integer>> response) {
                                            Platform.runLater(new Runnable() {
                                                @Override
                                                public void run() {
                                                    if(response.body().getCode()==1){
                                                        if(bFlag==0){
                                                            getTableViewData(null);
                                                        }else{
                                                            search();
                                                        }
                                                        Alert alert=new Alert(Alert.AlertType.CONFIRMATION,"设置样卷成功");
                                                        alert.showAndWait();
                                                    }
                                                }
                                            });
                                        }

                                        @Override
                                        public void onFailure(Call<Result<Integer>> call, Throwable t) {
                                            Platform.runLater(new Runnable() {
                                                @Override
                                                public void run() {
                                                    Alert alert=new Alert(Alert.AlertType.ERROR,"网络异常，请稍后重试");
                                                    alert.showAndWait();
                                                }
                                            });
                                        }
                                    },dataStore.getToken(),list);
                                    tableView.refresh();
                                }
                            });

                            Hyperlink h3=new Hyperlink("删除");
                            h3.setOnAction(new EventHandler<ActionEvent>(){
                                @Override
                                public void handle(ActionEvent event) {
                                    testPaperService.delTestPaper(new retrofit2.Callback<Result<Integer>>(){
                                        @Override
                                        public void onResponse(Call<Result<Integer>> call, Response<Result<Integer>> response) {
                                            Platform.runLater(new Runnable() {
                                                @Override
                                                public void run() {
                                                    int code = response.body().getCode();
                                                    String meg=response.body().getMsg();
                                                    if(code==1){
                                                        if(bFlag==0){
                                                            getTableViewData(null);
                                                        }else{
                                                            search();
                                                        }
                                                        Alert alert=new Alert(Alert.AlertType.CONFIRMATION,"删除成功");
                                                        alert.showAndWait();
                                                    }
                                                }
                                            });
                                        }

                                        @Override
                                        public void onFailure(Call<Result<Integer>> call, Throwable throwable) {
                                            Platform.runLater(new Runnable() {
                                                @Override
                                                public void run() {
                                                    Alert alert=new Alert(Alert.AlertType.ERROR,"网络异常，请稍后重试！");
                                                    alert.showAndWait();
                                                }
                                            });

                                        }
                                    },dataStore.getToken(),list);
                                }
                            });
                            hBox.getChildren().addAll(h1,h2,h3);
                            this.setGraphic(hBox);
                        }
                    }
                };
                return cell;
            }
        });
        tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);//表格自适应
        tableView.setTableMenuButtonVisible(true);
    }

    //未各个组件增加监听器
    public void setListener(){
        //为分页器增加监听事件
        page.currentPageIndexProperty().addListener(new ChangeListener<Number>() {
            @Override
            public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
                pageNumber=newValue.intValue()+1;
                if(bFlag==1){
                    search();
                }else {
                    getTableViewData(null);
                }
            }
        });
        //为分页器跳转输入框增加监听事件
        toPage.setOnKeyPressed(new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent event) {
                String pageNum=toPage.getText().trim();
                if(pageNum!=null&&!"".equals(pageNum)&&pageNum.trim().matches("^[0-9]*$")&&event.getCode()== KeyCode.ENTER){
                    page.setCurrentPageIndex(Integer.valueOf(pageNum)-1);
                }
            }
        });
    }

    //设置Combox
    public void setCourseNameCombox(){
        courseNameCombox.setItems(courseList);
        if(courseList.size()==1&&courseList.get(0).equals(defaultValue)){
            courseNameCombox.getSelectionModel().select(0);
        }
    }

    //获取课程信息
    public void getCombData(){
        //获取老师所加入课程的信息
        testPaperService.getCourseData(new retrofit2.Callback<Result<List<CourseData>>>() {
            @Override
            public void onResponse(Call<Result<List<CourseData>>> call, Response<Result<List<CourseData>>> response) {
                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                        courseList.clear();
                        courseDataList.clear();
                        courseDataList=response.body().getData();
                        if(courseDataList.size()!=0){
                            courseList.add(allValue);
                            courseDataList.forEach(courseData -> {
                                courseList.add(courseData.getName());
                            });
                        }else{
                            courseList.add(defaultValue);
                        }
                        setCourseNameCombox();
                    }
                });
            }
            @Override
            public void onFailure(Call<Result<List<CourseData>>>call, Throwable t) {
                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {

                    }
                });
            }
        },dataStore.getTeacher_id(),dataStore.getToken());

    }

    //删除试卷
    public void delete(ActionEvent actionEvent) {
        List<String> list=tableView.getItems().filtered(paperData -> paperData.getChecked()==true).stream().map(PaperData::getPapId).collect(Collectors.toList());
        testPaperService.delTestPaper(new retrofit2.Callback<Result<Integer>>() {
            @Override
            public void onResponse(Call<Result<Integer>> call, Response<Result<Integer>> response) {
                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                        if(response.body().getCode()==1){
                            if(bFlag==0){
                                getTableViewData(null);
                            }else{
                                search();
                            }
                            Alert alert=new Alert(Alert.AlertType.CONFIRMATION,"删除样卷成功");
                            alert.showAndWait();
                        }
                    }
                });
            }

            @Override
            public void onFailure(Call<Result<Integer>> call, Throwable t) {
                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                        Alert alert=new Alert(Alert.AlertType.ERROR,"网络异常，请稍后重试");
                        alert.showAndWait();
                    }
                });
            }
        },dataStore.getToken(),list);
        tableView.refresh();
    }

    //自动生成试卷
    public void auto(ActionEvent actionEvent) throws IOException {
        mainController.skipView("自动生成试卷");
    }

    //手动生成试卷
    public void generate(ActionEvent actionEvent) {
        mainController.skipView("手动生成试卷");
    }

    //搜索
    public void search(){
        if(courseNameCombox.getValue()!=""&&getCourseIdByName(courseDataList,courseNameCombox.getValue())!=""){
            bFlag=1;
            getTableViewData(getCourseIdByName(courseDataList,courseNameCombox.getValue()));
        }else{
            bFlag=0;
            getTableViewData(null);
        }
    }

    //发送请求，获取数据
    public void getTableViewData(String courseId){
        testPaperService.getPaperList(new retrofit2.Callback<Result<PaperInfo>>() {
            @Override
            public void onResponse(Call<Result<PaperInfo>> call, Response<Result<PaperInfo>> response) {
                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                        PaperInfo paperInfo=response.body().getData();
                        paperDatalist.clear();
                        tableView.getItems().clear();
                        paperInfo.getSubject().forEach(subjectData -> {
                            paperDatalist.add(new PaperData(subjectData.getPapId(),subjectData.getName(),subjectData.getTeaName(),subjectData.getCreateTime(),subjectData.getCourseName(),
                                    subjectData.getIsSample(),subjectData.getIsAB(),subjectData.getCollegeName(),false));
                        });
                        if(paperInfo.getCount()%8==0){
                            setTableViewItem(paperInfo.getCount()/8);
                        }else{
                            setTableViewItem(paperInfo.getCount()/8+1);
                        }
                    }
                });
            }

            @Override
            public void onFailure(Call<Result<PaperInfo>> call, Throwable t) {
                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {

                    }
                });
            }
        },dataStore.getToken(),dataStore.getTeacher_id(),courseId,pageNumber);
    }

    //设置TableView填充内容
    public void setTableViewItem(int num){
        tableView.setItems(paperDatalist);
        page.setPageCount(num);
        tableView.refresh();
        cb.setSelected(false);
    }

    //根据选中值获取课程ID
    public String getCourseIdByName(List<CourseData> list,String name){
        for(CourseData courseData:list){
            if(courseData.getName().equals(name)){
                return courseData.getId();
            }
        }
        if(allValue.equals(name)){
            return null;
        }
        return "";
    }

    //设为样卷
    public void setDisable(){
        List<String> list=tableView.getItems().filtered(paperData -> paperData.getChecked()==true).stream().map(PaperData::getPapId).collect(Collectors.toList());
        testPaperService.changePaperType(new retrofit2.Callback<Result<Integer>>() {
            @Override
            public void onResponse(Call<Result<Integer>> call, Response<Result<Integer>> response) {
                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                        if(response.body().getCode()==1){
                            if(bFlag==0){
                                getTableViewData(null);
                            }else{
                                search();
                            }
                            Alert alert=new Alert(Alert.AlertType.CONFIRMATION,"设置样卷成功");
                            alert.showAndWait();
                        }
                    }
                });
            }

            @Override
            public void onFailure(Call<Result<Integer>> call, Throwable t) {
                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                        Alert alert=new Alert(Alert.AlertType.ERROR,"网络异常，请稍后重试");
                        alert.showAndWait();
                    }
                });
            }
        },dataStore.getToken(),list);
    }

    //取消设为样卷
    public void setNoDisable(){
        List<String> list=tableView.getItems().filtered(paperData -> paperData.getChecked()==true).stream().map(PaperData::getPapId).collect(Collectors.toList());
        testPaperService.removePaperType(new retrofit2.Callback<Result<Integer>>() {
            @Override
            public void onResponse(Call<Result<Integer>> call, Response<Result<Integer>> response) {
                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                        if(response.body().getCode()==1){
                            if(bFlag==0){
                                getTableViewData(null);
                            }else{
                                search();
                            }
                            Alert alert=new Alert(Alert.AlertType.CONFIRMATION,"取消设为样卷成功");
                            alert.showAndWait();
                        }
                    }
                });
            }

            @Override
            public void onFailure(Call<Result<Integer>> call, Throwable t) {
                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                        Alert alert=new Alert(Alert.AlertType.ERROR,"网络异常，请稍后重试");
                        alert.showAndWait();
                    }
                });
            }
        },dataStore.getToken(),list);
    }

    //页面关闭清空所有数据
    public void clear(){
        pageNumber=1;
        courseList.clear();
        courseDataList.clear();
        paperDatalist.clear();
    }
}
